import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutterdemo/0demo/ui/custom_charts/overscroll_config/overscroll_config.dart';

class ScrollOffsetTestPage extends StatefulWidget {
  @override
  _ScrollOffsetTestPageState createState() => _ScrollOffsetTestPageState();
}

class _ScrollOffsetTestPageState extends State<ScrollOffsetTestPage> with SingleTickerProviderStateMixin {
  TabController _tabController;
  ScrollController _scrollController;

  GlobalKey _appBarKey = GlobalKey();
  List<String> _tabs = [];
  Map<String, GlobalKey> _globalKeys = Map();
  Map<String, double> _widgetOffsets = Map();
  double _appBarHeight;

  @override
  void initState() {
    _tabs.add("0");
    _tabs.add("1");
    _tabs.add("2");
    _tabs.add("3");
    _tabs.add("4");
    _tabs.add("5");
    _tabs.add("6");
    _tabs.add("7");

    _scrollController = ScrollController();
    _tabController = TabController(length: _tabs.length, vsync: this);

    _tabs.forEach((element) {
      GlobalKey globalKey = GlobalKey();
      _globalKeys[element] = globalKey;
    });

    WidgetsBinding.instance.addPostFrameCallback(_getWidgetPositionAndSize);
    _scrollController.addListener(_scrollListener);
    super.initState();
  }

  void _scrollListener() {
    double currentScrollDistance = _scrollController.offset;
    print("_scrollListener currentScrollDistance == " + currentScrollDistance.toString());
    String lastKey = "0";
    _widgetOffsets.forEach((key, widgetOffsetY) {
      if (currentScrollDistance > widgetOffsetY) {
        lastKey = key;
      }
    });

    if (currentScrollDistance == _scrollController.position.maxScrollExtent) {
      _tabController.animateTo(7);
      return;
    }

    if (0 == currentScrollDistance) {
      _tabController.animateTo(0);
      return;
    }

    int currentIndex = _tabController.index;
    int nextIndex = int.parse(lastKey);
    if (currentIndex != nextIndex) {
      if (!_tabController.indexIsChanging) {
        _tabController.animateTo(nextIndex);
      }
    }
  }

  // vpOffset 等价于 (offset.dy - _appBarHeight)
  // final RenderAbstractViewport viewport = RenderAbstractViewport.of(renderBox);
  // final RevealedOffset vpOffset = viewport.getOffsetToReveal(renderBox, 0);
  // print("vpOffset == " + vpOffset.toString());
  _scroll(String title) async {
    /// 注意：切换tab的时候不允许滑动，否则scroll监听冲突
    double widgetOffset = _widgetOffsets[title];
    if (widgetOffset == null) return;
    _scrollController.removeListener(_scrollListener);
    await Future.delayed(Duration(milliseconds: 100)); // 这个延时是等待tab滑动完成
    await _scrollController.animateTo(widgetOffset, duration: Duration(milliseconds: 100), curve: Curves.ease); //
    // duration 不能太大，否则还是会影响到tab
    await Future.delayed(Duration(milliseconds: 100)); // 这个延时是等待scroll滑动完成
    _scrollController.addListener(_scrollListener);
  }

  void _getWidgetPositionAndSize(_) {
    RenderBox appBarRenderBox = _appBarKey.currentContext.findRenderObject();
    Size appBarSize = appBarRenderBox.size;
    Offset appBarOffset = appBarRenderBox.localToGlobal(Offset.zero);
    print("appBarSize == " + appBarSize.toString() + "appBarOffset == " + appBarOffset.toString());
    _appBarHeight = appBarSize.height;

    _globalKeys.forEach((key, globalKey) {
      if (globalKey != null) {
        RenderBox renderBox = globalKey.currentContext.findRenderObject();
        Size size = renderBox.size;
        Offset offset = renderBox.localToGlobal(Offset.zero);
        print("size == " + size.toString() + "offsetY == " + (offset.dy - _appBarHeight).toString());
        _widgetOffsets[key] = offset.dy - _appBarHeight;
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: PreferredSize(
        preferredSize: Size.fromHeight(100),
        child: AppBar(
          key: _appBarKey,
          title: Text("scroll offset test"),
          bottom: TabBar(
            controller: _tabController,
            isScrollable: true,
            tabs: _tabs.map((String tab) {
              return Tab(
                text: tab + "aaaaa",
              );
            }).toList(),
            onTap: (value) {
              print("tap");
              _scroll(value.toString());
            },
          ),
        ),
      ),
      body: ScrollConfiguration(
        behavior: OverScrollBehavior(),
        child: CustomScrollView(
          controller: _scrollController,
          slivers: _getWidgetList(),
        ),
      ),
    );
  }

  List<Widget> _getWidgetList() {
    List<Widget> widgetList = [];

    _tabs.forEach((element) {
      GlobalKey key = GlobalKey();
      _globalKeys[element] = key;
      widgetList.add(
        SliverToBoxAdapter(
          child: ContentWidget(
            key: key,
            color: Colors.red,
            title: element,
          ),
        ),
      );
    });

    return widgetList;
  }
}

class ContentWidget extends StatelessWidget {
  final Color color;
  final String title;

  const ContentWidget({Key key, this.color, this.title}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 500,
      margin: EdgeInsets.all(10),
      color: color,
      child: Center(
        child: Text(title),
      ),
    );
  }
}
